home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / admin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-29  |  35.0 KB  |  1,595 lines

  1. /* 
  2.  * admin.c--
  3.  *
  4.  *    Simple utility functions for archive handlers
  5.  *
  6.  * Copyright 1992 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Quote:
  16.  *      "We should not introduce errors through sloppiness, we should do it
  17.  *      carefully and systematically."
  18.  *      -- Edsgar Dijkstra, A Discipline of Programming
  19.  */
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/admin.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  23. #endif /* not lint */
  24.  
  25. #include "jaquith.h"
  26.  
  27. extern int jDebug;            /* Internal debugging only */
  28. extern int syserr;            /* Our personal record of errno */
  29.  
  30. static char printBuf[T_MAXSTRINGLEN];
  31.  
  32. #define CNFGSUFFIX "/config"
  33. #define VOLSUFFIX "/volinfo"
  34. #define AUTHSUFFIX "/auth"
  35. #define FILESUFFIX "/filemap"
  36. #define CURSUFFIX "/tbuf"
  37. #define LRUSUFFIX "tbuf.lru"
  38. #define NEWSUFFIX "tbuf.lru.new"
  39. #define FREESUFFIX "/freevols"
  40. #define FREENEWSUFFIX ".new"
  41. #define VCOMMENT "# vol Id, filemark num, vol space (K), last buf Id\n"
  42. #define BCOMMENT "# buf size, hdr size, file cnt, buffer pad for tar\n"
  43. #define MCOMMENT "# vol Id, first tBuf Id\n"
  44. #define TCOMMENT "# Current tbuf number\n"
  45. #define CCOMMENT "# jmgr server, jmgr port, target buffer size\n"
  46. #define MINFREEVOLS 3
  47.  
  48.  
  49. /*
  50.  *----------------------------------------------------------------------
  51.  *
  52.  * Admin_CheckAuth --
  53.  *
  54.  *    Determine permissions for caller
  55.  *
  56.  * Results:
  57.  *    
  58.  *
  59.  * Side effects:
  60.  *    Allocates heap space.
  61.  *
  62.  *----------------------------------------------------------------------
  63.  */
  64.  
  65. int
  66. Admin_CheckAuth(archPath, callerPtr, permPtr)
  67.     char *archPath;           /* full path or archive */
  68.     Caller *callerPtr;        /* caller's id */
  69.     char *permPtr;            /* receiving permissions */
  70. {
  71.     char pathName[T_MAXPATHLEN];
  72.     FILE *archStream;
  73.     char *buf;
  74.     char namePattern[T_MAXLINELEN];
  75.     char groupPattern[T_MAXLINELEN];
  76.     char hostPattern[T_MAXLINELEN];
  77.     char *userName = callerPtr->userName;
  78.     char *groupName = callerPtr->groupName;
  79.     char *hostName = callerPtr->hostName;
  80.     char permString[T_MAXLINELEN];
  81.  
  82.     *permPtr = ' ';
  83.  
  84.     strcpy(pathName,archPath);
  85.     strcat(pathName, AUTHSUFFIX);
  86.  
  87.     if ((archStream=fopen(pathName, "r")) == (FILE *)NULL) {
  88.     syserr = errno;
  89.     if (access(archPath, X_OK) == -1) {
  90.         fprintf(stderr, "access for %s failed\n", pathName);
  91.         return T_NOARCHIVE;
  92.     } else {
  93.         fprintf(stderr, "open for %s failed: %d\n", pathName, syserr);
  94.         return T_NOACCESS;
  95.     }
  96.     }
  97.  
  98.     while ((buf=Utils_ReadLine(archStream, 1)) != NULL) {
  99.     if (sscanf(buf, "%s %s %s %s",
  100.            namePattern, groupPattern, hostPattern, permString) != 4) {
  101.         break;
  102.     }
  103.     if ((Str_Match(hostName, hostPattern)) &&
  104.         (Str_Match(groupName, groupPattern)) &&
  105.         (Str_Match(userName, namePattern))) {
  106.         *permString = toupper(*permString);
  107.         if (*permString == 'O') {
  108.         *permPtr = *permString;
  109.         break;
  110.         } else if ((*permString != 'R') || (*permPtr != 'W')) {
  111.         *permPtr = *permString;
  112.         }
  113.     }
  114.     } 
  115.  
  116.  
  117.     fclose(archStream);
  118.  
  119.     return T_SUCCESS;
  120. }
  121.  
  122.  
  123. /*
  124.  *----------------------------------------------------------------------
  125.  *
  126.  * Admin_AddAuth --
  127.  *
  128.  *    Add an entry to archive authorization file
  129.  *
  130.  * Results:
  131.  *    None.
  132.  *
  133.  * Side effects:
  134.  *    None.
  135.  *
  136.  *----------------------------------------------------------------------
  137.  */
  138.  
  139. int
  140. Admin_AddAuth(archPath, callerPtr, perm)
  141.     char *archPath;           /* full path or archive */
  142.     Caller *callerPtr;        /* caller's id */
  143.     char perm;                /* permission */
  144. {
  145.     char pathName[T_MAXPATHLEN];
  146.     FILE *archStream;
  147.     Lock_Handle lockHandle;
  148.  
  149.     strcpy(pathName,archPath);
  150.     strcat(pathName, AUTHSUFFIX);
  151.  
  152.     if (Lock_Acquire(pathName, LOCK_BLOCK, &lockHandle) != T_SUCCESS) {
  153.     return T_FAILURE;
  154.     }
  155.  
  156.     archStream = fopen(pathName, "a");
  157.     if (archStream == (FILE *)NULL) {
  158.     syserr = errno;
  159.     Lock_Release(&lockHandle);
  160.     if (syserr == ENOENT) {
  161.         return T_NOARCHIVE;
  162.     } else {
  163.         return T_FAILURE;
  164.     }
  165.     }
  166.  
  167.     fprintf(archStream, "%s %s %s %c\n",
  168.         callerPtr->userName, callerPtr->groupName, 
  169.         callerPtr->hostName, perm);
  170.  
  171.     Lock_Release(&lockHandle);
  172.     fclose(archStream);
  173.  
  174.     return T_SUCCESS;
  175. }
  176.  
  177.  
  178.  
  179. /*
  180.  *----------------------------------------------------------------------
  181.  *
  182.  * Admin_ReadArchConfig
  183.  *
  184.  *    Read the archive's config file
  185.  *
  186.  * Results:
  187.  *    current config data
  188.  *
  189.  * Side effects:
  190.  *    None.
  191.  *
  192.  *----------------------------------------------------------------------
  193.  */
  194.  
  195. int
  196. Admin_ReadArchConfig(archPath, archConfigPtr)
  197.     char *archPath;           /* full path or archive */
  198.     ArchConfig *archConfigPtr;     /* Receiving space */
  199. {
  200.     char pathName[T_MAXPATHLEN];
  201.     FILE *archStream;
  202.     char *buf;
  203.     int retCode = T_SUCCESS;
  204.  
  205.     strcpy(pathName,archPath);
  206.     strcat(pathName, CNFGSUFFIX);
  207.  
  208.     archStream = fopen(pathName, "r");
  209.     if (archStream == (FILE *)NULL) {
  210.     if (errno == ENOENT)  {
  211.         strcpy(archConfigPtr->mgrServer,DEF_MGRSERVER);
  212.         archConfigPtr->mgrPort = DEF_MGRPORT;
  213.         archConfigPtr->tBufSize = DEF_TBUFSIZE;
  214.         return Admin_WriteArchConfig(archPath, archConfigPtr);
  215.     } else {
  216.         syserr = errno;
  217.     }
  218.     } else {
  219.     buf = Utils_ReadLine(archStream, 1);
  220.     if (sscanf(buf, "%s %d %d",
  221.            archConfigPtr->mgrServer,
  222.            &archConfigPtr->mgrPort,
  223.            &archConfigPtr->tBufSize) != 3) {
  224.         syserr = EINVAL;
  225.         retCode = T_ADMFAILED;
  226.     }
  227.     fclose(archStream);
  228.     }
  229.  
  230.     return retCode;
  231.     
  232. }
  233.  
  234.  
  235. /*
  236.  *----------------------------------------------------------------------
  237.  *
  238.  * Admin_WriteArchConfig
  239.  *
  240.  *    Write the current configuration info
  241.  *
  242.  * Results:
  243.  *    None.
  244.  *
  245.  * Side effects:
  246.  *    Will (re)create file 'config' in logical archive
  247.  *
  248.  *----------------------------------------------------------------------
  249.  */
  250.  
  251. int
  252. Admin_WriteArchConfig(archPath, archConfigPtr)
  253.     char *archPath;           /* full path or archive */
  254.     ArchConfig *archConfigPtr;     /* Source info */
  255. {
  256.     char pathName[T_MAXPATHLEN];
  257.     FILE *archStream;
  258.     int retCode = T_SUCCESS;
  259.  
  260.     strcpy(pathName,archPath);
  261.     strcat(pathName, CNFGSUFFIX);
  262.  
  263.     archStream = fopen(pathName, "w");
  264.     if (archStream == (FILE *)NULL) {
  265.     syserr = errno;
  266.     retCode = T_ADMFAILED;
  267.     } else {
  268.     fprintf(archStream, "%s%s %d %d\n",
  269.         CCOMMENT, archConfigPtr->mgrServer,
  270.         archConfigPtr->mgrPort,    archConfigPtr->tBufSize);
  271.     fclose(archStream);
  272.     }
  273.  
  274.     return retCode;
  275.     
  276. }
  277.  
  278. /*
  279.  *----------------------------------------------------------------------
  280.  *
  281.  * Admin_GetCurTBuf
  282.  *
  283.  *    Read the current tbuf number
  284.  *
  285.  * Results:
  286.  *    current tbufId
  287.  *
  288.  * Side effects:
  289.  *    None.
  290.  *
  291.  *----------------------------------------------------------------------
  292.  */
  293.  
  294. int
  295. Admin_GetCurTBuf(archPath, tBufIdPtr)
  296.     char *archPath;           /* full path or archive */
  297.     int *tBufIdPtr;           /* Receiving space */
  298. {
  299.     char pathName[T_MAXPATHLEN];
  300.     FILE *archStream;
  301.     char *buf;
  302.     int retCode = T_SUCCESS;
  303.     Lock_Handle lockHandle;
  304.  
  305.     strcpy(pathName,archPath);
  306.     strcat(pathName, CURSUFFIX);
  307.  
  308.     if (Lock_Acquire(pathName, LOCK_BLOCK, &lockHandle) != T_SUCCESS) {
  309.     return T_FAILURE;
  310.     }
  311.  
  312.     archStream = fopen(pathName, "r");
  313.     if (archStream == (FILE *)NULL) {
  314.     if (errno == ENOENT)  {
  315.         Lock_Release(&lockHandle);
  316.         return Admin_SetCurTBuf(archPath, 0);
  317.     }
  318.     } else {
  319.     buf = Utils_ReadLine(archStream, 1);
  320.     sscanf(buf, "%d", tBufIdPtr);
  321.     fclose(archStream);
  322.     Lock_Release(&lockHandle);
  323.     }
  324.  
  325.     return retCode;
  326.     
  327. }
  328.  
  329.  
  330. /*
  331.  *----------------------------------------------------------------------
  332.  *
  333.  * Admin_SetCurTbuf
  334.  *
  335.  *    Write the current tbuf number
  336.  *
  337.  * Results:
  338.  *    current tbufId
  339.  *
  340.  * Side effects:
  341.  *    Will (re)create file 'tbuf' in logical archive
  342.  *
  343.  * Note:
  344.  *      Locking necessary to synchronize writer and cleaner.
  345.  *
  346.  *----------------------------------------------------------------------
  347.  */
  348.  
  349. int
  350. Admin_SetCurTBuf(archPath, tBufId)
  351.     char *archPath;           /* full path or archive */
  352.     int tBufId;               /* buffer id */
  353. {
  354.     char pathName[T_MAXPATHLEN];
  355.     FILE *archStream;
  356.     int retCode = T_SUCCESS;
  357.     Lock_Handle lockHandle;
  358.  
  359.     strcpy(pathName,archPath);
  360.     strcat(pathName, CURSUFFIX);
  361.  
  362.     if (Lock_Acquire(pathName, LOCK_BLOCK, &lockHandle) != T_SUCCESS) {
  363.     return T_FAILURE;
  364.     }
  365.  
  366.     archStream = fopen(pathName, "w");
  367.     if (archStream == (FILE *)NULL) {
  368.     syserr = errno;
  369.     retCode = T_ADMFAILED;
  370.     } else {
  371.     fprintf(archStream, "%s%d\n", TCOMMENT, tBufId);
  372.     fsync(fileno(archStream));
  373.     fclose(archStream);
  374.     }
  375.  
  376.     Lock_Release(&lockHandle);
  377.  
  378.     return retCode;
  379.     
  380. }
  381.  
  382.  
  383. /*
  384.  *----------------------------------------------------------------------
  385.  *
  386.  * Admin_AvailVolInfo --
  387.  *
  388.  *    Check to see if volinfo is available; ie whether
  389.  *      a cleaner exists. This is used by jupdate so it
  390.  *      knows whether it needs to spaqn a new cleaner.
  391.  *      A race exists between the check and the action
  392.  *      but it doesn't matter; it's just a performance hack.
  393.  *
  394.  * Results:
  395.  *    return code
  396.  *
  397.  * Side effects:
  398.  *    None.
  399.  *
  400.  *----------------------------------------------------------------------
  401.  */
  402.  
  403. int
  404. Admin_AvailVolInfo(archPath)
  405.     char *archPath;           /* full path of archive */
  406. {
  407.    char pathName[T_MAXPATHLEN];    
  408.    int retCode;
  409.  
  410.    strcpy(pathName, archPath);
  411.    strcat(pathName, VOLSUFFIX);
  412.    strcat(pathName, ".LOCK");
  413.  
  414.    retCode = access(pathName, R_OK);
  415.  
  416.    return ((retCode == -1) ? 1 : 0);
  417.  
  418. }
  419.  
  420.  
  421.  
  422. /*
  423.  *----------------------------------------------------------------------
  424.  *
  425.  * Admin_OpenVolInfo --
  426.  *
  427.  *    Open and lock the volume file for modifications
  428.  *
  429.  * Results:
  430.  *    return code
  431.  *
  432.  * Side effects:
  433.  *    None.
  434.  *
  435.  *----------------------------------------------------------------------
  436.  */
  437.  
  438. FILE *
  439. Admin_OpenVolInfo(archPath, lockHandlePtr)
  440.     char *archPath;           /* Full path of archive */
  441.     Lock_Handle *lockHandlePtr; /* Receiving lock handle */
  442. {
  443.     char pathName[T_MAXPATHLEN];
  444.     FILE *volStream;
  445.     VolInfo vInfo;
  446.  
  447.     strcpy(pathName,archPath);
  448.     strcat(pathName, VOLSUFFIX);
  449.  
  450.     if (Lock_Acquire(pathName, LOCK_NOBLOCK, lockHandlePtr) != T_SUCCESS) {
  451.     return NULL;
  452.     }
  453.  
  454.     volStream = fopen(pathName, "r+");
  455.     if (volStream == (FILE *)NULL) {
  456.     if (errno == ENOENT)  {
  457.         if ((volStream = fopen(pathName, "w+")) != (FILE *)NULL) {
  458.         vInfo.volId = -1;
  459.         vInfo.filemark = 0;
  460.         vInfo.volSpace = -1;
  461.         vInfo.lastTBuf = -1;
  462.         Admin_WriteVolInfo(volStream, &vInfo);
  463.         }
  464.     }
  465.     }
  466.  
  467.     if (volStream == (FILE *)NULL) {
  468.     syserr = errno;
  469.     fprintf(stderr,"Admin_OpenVolInfo: couldn't open %s\n",pathName);
  470.     }
  471.  
  472.     return volStream;
  473.  
  474. }
  475.  
  476.  
  477. /*
  478.  *----------------------------------------------------------------------
  479.  *
  480.  * Admin_CloseVolInfo --
  481.  *
  482.  *    Close and unlock the volume file
  483.  *
  484.  * Results:
  485.  *    return code
  486.  *
  487.  * Side effects:
  488.  *    None.
  489.  *
  490.  *----------------------------------------------------------------------
  491.  */
  492.  
  493. int
  494. Admin_CloseVolInfo(lockHandlePtr, volStream)
  495.     Lock_Handle *lockHandlePtr;  /* item to unlock */
  496.     FILE *volStream;          /* associated file stream ptr */
  497. {
  498.     fclose(volStream);
  499.     Lock_Release(lockHandlePtr);
  500.     return T_SUCCESS;
  501. }
  502.  
  503.  
  504.  
  505. /*
  506.  *----------------------------------------------------------------------
  507.  *
  508.  * Admin_ReadVolInfo --
  509.  *
  510.  *    Read the current volume state 
  511.  *
  512.  * Results:
  513.  *    Filled in structure.
  514.  *
  515.  * Side effects:
  516.  *    None.
  517.  *
  518.  *----------------------------------------------------------------------
  519.  */
  520.  
  521. int
  522. Admin_ReadVolInfo(volStream, vInfoPtr)
  523.     FILE *volStream;          /* stream designator */
  524.     VolInfo *vInfoPtr;        /* receiving structure */
  525. {
  526.     char *buf;
  527.     int retCode = T_SUCCESS;
  528.  
  529.     rewind(volStream);
  530.     if ((buf=Utils_ReadLine(volStream, 1)) == (char *)NULL) {
  531.     fprintf(stderr,"Admin_ReadVolInfo: No data in volinfo file.\n");
  532.     retCode = T_ADMFAILED;
  533.     } else {
  534.     sscanf(buf, "%d %d %d %d",
  535.            &vInfoPtr->volId, &vInfoPtr->filemark,
  536.            &vInfoPtr->volSpace, &vInfoPtr->lastTBuf);
  537.     }
  538.  
  539.     return retCode;
  540. }
  541.  
  542.  
  543. /*
  544.  *----------------------------------------------------------------------
  545.  *
  546.  * Admin_WriteVolInfo --
  547.  *
  548.  *    Update the current volume state 
  549.  *
  550.  * Results:
  551.  *    return code.
  552.  *
  553.  * Side effects:
  554.  *    Modifies archive data file.
  555.  *
  556.  *----------------------------------------------------------------------
  557.  */
  558.  
  559. int
  560. Admin_WriteVolInfo(volStream, vInfoPtr)
  561.     FILE *volStream;          /* stream designator */
  562.     VolInfo *vInfoPtr;        /* receiving structure */
  563. {
  564.     int retCode = T_SUCCESS;
  565.  
  566.     rewind(volStream);
  567.     fprintf(volStream, "%s%d %d %d %d\n",
  568.         VCOMMENT, vInfoPtr->volId, vInfoPtr->filemark,
  569.         vInfoPtr->volSpace, vInfoPtr->lastTBuf);
  570.     /*
  571.      * Unfortunately, we must pay the price here because
  572.      * we're just about to delete the buffer.
  573.      */
  574.     fsync(fileno(volStream));
  575.  
  576.     return retCode;
  577.  
  578. }
  579.  
  580.  
  581. /*
  582.  *----------------------------------------------------------------------
  583.  *
  584.  * Admin_OpenMetaInfo --
  585.  *
  586.  *    Open the meta file
  587.  *
  588.  * Results:
  589.  *    return code
  590.  *
  591.  * Side effects:
  592.  *    None.
  593.  *
  594.  *----------------------------------------------------------------------
  595.  */
  596.  
  597. FILE *
  598. Admin_OpenMetaInfo(archPath, tBufId)
  599.     char *archPath;           /* full path of archive */
  600.     int tBufId;               /* active tbuf id number */
  601. {
  602.     char pathName[T_MAXPATHLEN];
  603.     FILE *metaStream;
  604.     MetaInfo metaInfo;
  605.  
  606.     sprintf(pathName, "%s/meta.%d%c", archPath, tBufId, '\0');
  607.  
  608.     metaStream = fopen(pathName, "r+");
  609.     if (metaStream == (FILE *)NULL) {
  610.     if (errno == ENOENT)  {
  611.         if ((metaStream=fopen(pathName, "w+")) != (FILE *)NULL) {
  612.             metaInfo.tBufSize = 0;
  613.             metaInfo.tHdrSize = T_TBLOCK; /* Size of tar hdr. sorry */
  614.             metaInfo.fileCnt = 0;
  615.             metaInfo.tBufPad = 0;
  616.             Admin_WriteMetaInfo(metaStream, &metaInfo);
  617.         fflush(metaStream);
  618.         }
  619.     }
  620.     }
  621.  
  622.     if (metaStream == (FILE *)NULL) {
  623.     syserr = errno;
  624.     fprintf(stderr,"Admin_OpenMetaInfo: couldn't open %s\n",pathName);
  625.     }
  626.  
  627.     return metaStream;
  628.  
  629. }
  630.  
  631.  
  632. /*
  633.  *----------------------------------------------------------------------
  634.  *
  635.  * Admin_CloseMetaInfo --
  636.  *
  637.  *    Close meta file
  638.  *
  639.  * Results:
  640.  *    return code
  641.  *
  642.  * Side effects:
  643.  *    None.
  644.  *
  645.  *----------------------------------------------------------------------
  646.  */
  647.  
  648. int
  649. Admin_CloseMetaInfo(metaStream)
  650.     FILE *metaStream;         /* associated file stream ptr */
  651. {
  652.     fclose(metaStream);
  653.     return T_SUCCESS;
  654. }
  655.  
  656.  
  657. /*
  658.  *----------------------------------------------------------------------
  659.  *
  660.  * Admin_ReadMetaInfo --
  661.  *
  662.  *    Read the current buffer state 
  663.  *
  664.  * Results:
  665.  *    Ptr to block of specified size or NULL;
  666.  *
  667.  * Side effects:
  668.  *    Allocates heap space.
  669.  *
  670.  * Note:
  671.  *     Locking shouldn't be necessary. Jupdate and Jclean 
  672.  *     don't share the same tbufs.
  673.  * 
  674.  *----------------------------------------------------------------------
  675.  */
  676.  
  677. int
  678. Admin_ReadMetaInfo(metaStream, metaInfoPtr)
  679.     FILE *metaStream;         /* associated file stream ptr */
  680.     MetaInfo *metaInfoPtr;    /* receiving structure */
  681. {
  682.     char *buf;
  683.     int retCode = T_SUCCESS;
  684.  
  685.     rewind(metaStream);
  686.     if ((buf=Utils_ReadLine(metaStream, 1)) == (char *)NULL) {
  687.     retCode = T_ADMFAILED;
  688.     } else {
  689.         sscanf(buf, "%d %d %d %d",
  690.            &metaInfoPtr->tBufSize,
  691.            &metaInfoPtr->tHdrSize,
  692.            &metaInfoPtr->fileCnt,
  693.            &metaInfoPtr->tBufPad);
  694.     }
  695.  
  696.     return retCode;
  697.  
  698. }
  699.  
  700.  
  701. /*
  702.  *----------------------------------------------------------------------
  703.  *
  704.  * Admin_WriteMetaInfo --
  705.  *
  706.  *    Update the current buffer state 
  707.  *
  708.  * Results:
  709.  *    return code.
  710.  *
  711.  * Side effects:
  712.  *    Modifies archive data file.
  713.  *
  714.  * Note:
  715.  *     Locking shouldn't be necessary. Only Jupdate calls this routine.
  716.  *     Jupdate decides whether or not to do an fsync.
  717.  *
  718.  *----------------------------------------------------------------------
  719.  */
  720.  
  721. int
  722. Admin_WriteMetaInfo(metaStream, metaInfoPtr)
  723.     FILE *metaStream;         /* associated file stream ptr */
  724.     MetaInfo *metaInfoPtr;    /* receiving structure */
  725. {
  726.     int retCode = T_SUCCESS;
  727.  
  728.     rewind(metaStream);
  729.     fprintf(metaStream, "%s%d %d %d %d\n",
  730.         BCOMMENT, metaInfoPtr->tBufSize, metaInfoPtr->tHdrSize,
  731.         metaInfoPtr->fileCnt, metaInfoPtr->tBufPad);
  732.  
  733.     return retCode;
  734. }
  735.  
  736.  
  737. /*
  738.  *----------------------------------------------------------------------
  739.  *
  740.  * Admin_CvtTBufId --
  741.  *
  742.  *    Convert a buffer number to a volId and filemark pair.
  743.  *
  744.  * Results:
  745.  *    volume Id
  746.  *      block Id
  747.  *
  748.  * Side effects:
  749.  *    Modifies archive data file.
  750.  *
  751.  *----------------------------------------------------------------------
  752.  */
  753.  
  754. int
  755. Admin_CvtTBufId(archPath, tBufId, volIdPtr, filemarkPtr)
  756.     char *archPath;           /* path to active archive */
  757.     int tBufId;               /* source buffer id */
  758.     int *volIdPtr;            /* receiving volume id */
  759.     int *filemarkPtr;         /* receiving block id */
  760. {
  761.     char pathName[T_MAXPATHLEN];
  762.     FILE *fileStream;
  763.     int tmpVolId;
  764.     int newTBufId;
  765.     int tmpTBufId;
  766.     int retCode = T_ADMFAILED;
  767.     char *bufPtr;
  768.  
  769.     strcpy(pathName,archPath);
  770.     strcat(pathName, FILESUFFIX);
  771.  
  772.     *volIdPtr = -1;
  773.     *filemarkPtr = -1;
  774.  
  775.     fileStream = fopen(pathName, "r");
  776.     if (fileStream == (FILE *)NULL) {
  777.     retCode == T_SUCCESS;
  778.     } else {
  779.     while ((bufPtr=Utils_ReadLine(fileStream, 1)) != NULL) {
  780.         if (sscanf(bufPtr, "%d %d", &tmpVolId, &tmpTBufId) != 2) {
  781.         break;
  782.         }
  783.         if (tBufId < tmpTBufId) {
  784.         break;
  785.         }
  786.         *volIdPtr = tmpVolId;
  787.         newTBufId = tmpTBufId;
  788.     }
  789.     if (*volIdPtr != -1) {
  790.         *filemarkPtr = 2*(tBufId - newTBufId);
  791.         retCode = T_SUCCESS;
  792.     }
  793.     fclose(fileStream);
  794.     }
  795.  
  796.     return retCode;
  797.  
  798. }
  799.  
  800.  
  801.  
  802. /*
  803.  *----------------------------------------------------------------------
  804.  *
  805.  * Admin_AddTBufId --
  806.  *
  807.  *    Add a new volume-tBufId pair to list
  808.  *
  809.  * Results:
  810.  *    None.
  811.  *
  812.  * Side effects:
  813.  *    Modifies archive data file.
  814.  *
  815.  *----------------------------------------------------------------------
  816.  */
  817.  
  818. int
  819. Admin_AddTBufId(archPath, volId, tBufId)
  820.     char *archPath;           /* archive */
  821.     int volId;                /* new volume */
  822.     int tBufId;               /* starting tbuf id */
  823. {
  824.     char pathName[T_MAXPATHLEN];
  825.     FILE *fileStream;
  826.     int retCode = T_SUCCESS;
  827.     Lock_Handle lockHandle;
  828.     time_t curDate;
  829.  
  830.     strcpy(pathName,archPath);
  831.     strcat(pathName, FILESUFFIX);
  832.  
  833.     if (Lock_Acquire(pathName, LOCK_BLOCK, &lockHandle) != T_SUCCESS) {
  834.     return T_FAILURE;
  835.     }
  836.  
  837.     fileStream = fopen(pathName, "a");
  838.     if (fileStream == (FILE *)NULL) {
  839.     syserr = errno;
  840.     fprintf(stderr,"Admin_AddTBufId: couldn't open %s\n",pathName);
  841.     retCode = T_ADMFAILED;
  842.     } else {
  843.     if (ftell(fileStream) == 0) {
  844.         fprintf(fileStream, "%s", MCOMMENT);
  845.     }
  846.     curDate = Time_GetCurDate();
  847.     fprintf(fileStream, "%d %d %s\n",
  848.         volId, tBufId, Time_CvtToString(&curDate));
  849.     fclose(fileStream);
  850.     }
  851.  
  852.     Lock_Release(&lockHandle);
  853.     return retCode;
  854.  
  855. }
  856.  
  857. /*
  858.  *----------------------------------------------------------------------
  859.  *
  860.  * Admin_UpdateLRU --
  861.  *
  862.  *    Update tbuf LRU list
  863.  *
  864.  * Results:
  865.  *    return code
  866.  *
  867.  * Side effects:
  868.  *    Rewrites LRU list
  869.  *
  870.  *----------------------------------------------------------------------
  871.  */
  872.  
  873. int
  874. Admin_UpdateLRU(rootPath, archive, firstTBuf, lastTBuf)
  875.     char *rootPath;           /* path to root */
  876.     char *archive;            /* archive name */
  877.     int firstTBuf;            /* fist tBufId to update */
  878.     int lastTBuf;             /* last tBufId to update */
  879. {
  880.     FILE *lruStream;
  881.     FILE *newStream;
  882.     char lruPath[T_MAXPATHLEN];
  883.     char newPath[T_MAXPATHLEN];
  884.     char oldArch[T_MAXPATHLEN];
  885.     int tBufId;
  886.     char *bufPtr;
  887.     Lock_Handle lockHandle;
  888.  
  889.     strcpy(lruPath, rootPath);
  890.     strcat(lruPath, "/");
  891.     strcat(lruPath, LRUSUFFIX);
  892.  
  893.     strcpy(newPath, rootPath);
  894.     strcat(newPath, "/");
  895.     strcat(newPath, NEWSUFFIX);
  896.  
  897.     if (Lock_Acquire(lruPath, LOCK_BLOCK, &lockHandle) != T_SUCCESS) {
  898.     return T_FAILURE;
  899.     }
  900.  
  901.     lruStream = fopen(lruPath, "r");
  902.     if (lruStream == (FILE *)NULL) {
  903.     if (errno != ENOENT) {
  904.         Lock_Release(&lockHandle);
  905.         return -1;
  906.     }
  907.     }
  908.  
  909.     newStream = fopen(newPath, "w");
  910.     if (newStream == (FILE *)NULL) {
  911.     syserr = errno;
  912.     Lock_Release(&lockHandle);
  913.     return T_FAILURE;
  914.     }
  915.  
  916.     for (tBufId=lastTBuf; tBufId >= firstTBuf; tBufId--) {
  917.         fprintf(newStream, "%s %d\n", archive, tBufId);
  918.     }
  919.  
  920.     if (lruStream != (FILE *)NULL) {
  921.     while ((bufPtr=Utils_ReadLine(lruStream, 0)) != NULL) {
  922.         sscanf(bufPtr,"%s %d\n", oldArch, &tBufId);
  923.         if ((tBufId < firstTBuf) ||
  924.         (tBufId > lastTBuf) ||
  925.         (strcmp(oldArch,archive) != 0)) {
  926.         fputs(bufPtr, newStream);
  927.         }
  928.     }
  929.     fclose(lruStream);
  930.     unlink(lruPath);
  931.     }
  932.  
  933.     fclose(newStream);
  934.     rename(newPath, lruPath);
  935.     Lock_Release(&lockHandle);
  936.     return T_SUCCESS;
  937.  
  938. }
  939.  
  940.  
  941.  
  942. /*
  943.  *----------------------------------------------------------------------
  944.  *
  945.  * Admin_RemoveLRU --
  946.  *
  947.  *    Remove a tape buffer from LRU list
  948.  *
  949.  * Results:
  950.  *    return code
  951.  *
  952.  * Side effects:
  953.  *    Rewrites LRU list
  954.  *
  955.  *----------------------------------------------------------------------
  956.  */
  957.  
  958. int 
  959. Admin_RemoveLRU(rootPath, archive, tBufIdPtr)
  960.     char *rootPath;           /* path to this archive */
  961.     char *archive;            /* ptr to receiving archive */
  962.     int *tBufIdPtr;           /* receiving tbuf number */
  963. {
  964.     FILE *lruStream;
  965.     char lruPath[T_MAXPATHLEN];
  966.     char *bufPtr;
  967.     int pos = 0;
  968.     int oldPos;
  969.     int retCode = T_FAILURE;
  970.     Lock_Handle lockHandle;
  971.  
  972.     strcpy(lruPath, rootPath);
  973.     strcat(lruPath, "/");
  974.     strcat(lruPath, LRUSUFFIX);
  975.  
  976.     if (Lock_Acquire(lruPath, LOCK_BLOCK, &lockHandle) != T_SUCCESS) {
  977.     return T_FAILURE;
  978.     }
  979.  
  980.     lruStream = fopen(lruPath, "r");
  981.     syserr = errno;
  982.  
  983.     if (lruStream != (FILE *)NULL) {
  984.     while ((bufPtr=Utils_ReadLine(lruStream, 1)) != NULL) {
  985.         sscanf(bufPtr, "%s %d", archive, tBufIdPtr);
  986.         oldPos = pos;
  987.         pos = ftell(lruStream);
  988.         retCode = T_SUCCESS;
  989.     }
  990.     fclose(lruStream);
  991.     }
  992.  
  993.     if (retCode == T_SUCCESS) {
  994.     truncate(lruPath, oldPos);
  995.     }
  996.  
  997.     Lock_Release(&lockHandle);
  998.     return retCode;
  999.  
  1000. }
  1001.  
  1002.  
  1003. /*
  1004.  *----------------------------------------------------------------------
  1005.  *
  1006.  * Admin_GetDiskUse --
  1007.  *
  1008.  *    Figure out how much of the disk is in use
  1009.  *
  1010.  * Results:
  1011.  *    None.
  1012.  *
  1013.  * Side effects:
  1014.  *    None.
  1015.  *
  1016.  * Note:
  1017.  *      Really need to take into account # of free inodes
  1018.  *      and disk quota, if any, but too much trouble.
  1019.  *
  1020.  *----------------------------------------------------------------------
  1021.  */
  1022.  
  1023. #ifdef sprite
  1024. #include <sys/types.h>
  1025. #include <sys/stat.h>
  1026. #include <sprite.h>
  1027. #include <fs.h>
  1028. #include <sysStats.h>
  1029.  
  1030. int
  1031. Admin_GetDiskUse(fileName, percentUsedPtr, blocksFreePtr)
  1032.     char *fileName;           /* File system to check */
  1033.     int *percentUsedPtr;      /* Percent of banks free */
  1034.     long *blocksFreePtr;      /* Number of free blocks */
  1035. {
  1036.     Fs_Prefix prefix;
  1037.     struct stat unixStatBuf;
  1038.     int tot;
  1039.     int numDomain = 0;
  1040.  
  1041.     if (stat(fileName, &unixStatBuf) < 0) {
  1042.     return T_FAILURE;
  1043.     }
  1044.         
  1045.     while (Sys_Stats(SYS_FS_PREFIX_STATS, numDomain++, (Address) &prefix)
  1046.        == SUCCESS) {
  1047.     if ((prefix.serverID == unixStatBuf.st_serverID) &&
  1048.         (prefix.domain == ((int) unixStatBuf.st_dev))) {
  1049.         tot = 0.9 * prefix.domainInfo.maxKbytes;
  1050.         *blocksFreePtr = prefix.domainInfo.freeKbytes -
  1051.         (0.1 * prefix.domainInfo.maxKbytes);
  1052.         *percentUsedPtr = (int) (100.0 * ((tot-*blocksFreePtr) /
  1053.                           (float) tot));
  1054.         return T_SUCCESS;
  1055.     }
  1056.     }
  1057.  
  1058.     return 0;
  1059.  
  1060. }
  1061.  
  1062. #endif
  1063.  
  1064. #ifdef ultrix
  1065.  
  1066. #include <sys/types.h>
  1067. #include <sys/param.h>
  1068. #include <sys/mount.h>
  1069.  
  1070. int
  1071. Admin_GetDiskUse(fileName, percentUsedPtr, blocksFreePtr)
  1072.     char *fileName;           /* File system to check */
  1073.     int *percentUsedPtr;      /* Percent of banks free */
  1074.     long *blocksFreePtr;      /* Number of free blocks */
  1075. {
  1076.     struct fs_data statFsBuf;
  1077.     int tot;
  1078.  
  1079.     if (statfs(fileName, &statFsBuf) == -1) {
  1080.     return T_FAILURE;
  1081.     } else {
  1082.     tot = statFsBuf.fd_req.btot * 0.9; /* 10% is reserved */
  1083.     *blocksFreePtr = statFsBuf.fd_req.bfreen;
  1084.     *percentUsedPtr = (int) (100.0 * ((tot-*blocksFreePtr) /
  1085.                       (float) tot));
  1086.     return T_SUCCESS;
  1087.     }
  1088.  
  1089. }
  1090.  
  1091. #endif
  1092.  
  1093. #if (!defined(sprite) && !defined(ultrix))
  1094.  
  1095. #include <sys/types.h>
  1096. #ifdef OSF1
  1097. #include <sys/mount.h>
  1098. #else
  1099. #include <sys/vfs.h>
  1100. #endif
  1101. int
  1102. Admin_GetDiskUse(fileName, percentUsedPtr, blocksFreePtr)
  1103.     char *fileName;           /* File system to check */
  1104.     int *percentUsedPtr;      /* Percent of banks free */
  1105.     long *blocksFreePtr;      /* Number of free blocks */
  1106. {
  1107.     struct statfs statFsBuf;
  1108.     long tot;
  1109.  
  1110.     if (statfs(fileName, &statFsBuf) == -1) {
  1111.     return T_FAILURE;
  1112.     } else {
  1113.     tot = statFsBuf.f_blocks;
  1114.     *blocksFreePtr = statFsBuf.f_bavail;
  1115.     *percentUsedPtr = (int) (100.0 * ((tot-*blocksFreePtr) /
  1116.                       (float) tot));
  1117.     return T_SUCCESS;
  1118.     }
  1119.  
  1120. }
  1121.  
  1122. #endif
  1123.  
  1124.  
  1125. /*
  1126.  *----------------------------------------------------------------------
  1127.  *
  1128.  * Admin_FindVolOwner --
  1129.  *
  1130.  *    Scan the filemaps to locate owner of specified volume
  1131.  *
  1132.  * Results:
  1133.  *    ptr to static string or NULL
  1134.  *
  1135.  * Side effects:
  1136.  *    None.
  1137.  *
  1138.  *----------------------------------------------------------------------
  1139.  */
  1140.  
  1141. VolOwner *
  1142. Admin_FindVolOwner(volId, root, archPattern)
  1143.     int volId;                /* volume of interest */
  1144.     char *root;               /* root of tree */
  1145.     char *archPattern;        /* archives to search */
  1146. {
  1147.     char pathName[T_MAXPATHLEN];
  1148.     FILE *fileStream;
  1149.     DIR *rootDirPtr;
  1150.     DirObject *entryPtr;
  1151.     struct stat unixStatBuf;
  1152.     char *bufPtr;
  1153.     int tmpTBufId;
  1154.     int tmpVolId;
  1155.     static VolOwner volOwner;
  1156.  
  1157.     volOwner.owner = NULL;
  1158.     volOwner.minTBuf = -1;
  1159.     volOwner.maxTBuf = -1;
  1160.  
  1161.     if ((rootDirPtr=(DIR *)opendir(root)) == (DIR *) NULL) {
  1162.     return NULL;
  1163.     }
  1164.  
  1165.     while ((entryPtr=readdir(rootDirPtr)) != (DirObject *)NULL) {
  1166.     if ((*entryPtr->d_name != '.') &&
  1167.         (Str_Match(entryPtr->d_name, archPattern))) {
  1168.         strcpy(pathName, root);
  1169.         strcat(pathName, "/");
  1170.         strcat(pathName, entryPtr->d_name);
  1171.         stat(pathName, &unixStatBuf);
  1172.         if (!S_ISADIR(unixStatBuf.st_mode)) {
  1173.             continue;
  1174.         }
  1175.         strcat(pathName, FILESUFFIX);
  1176.         fileStream = fopen(pathName, "r");
  1177.         if (fileStream != (FILE *)NULL) {
  1178.         while ((bufPtr=Utils_ReadLine(fileStream, 1)) != NULL) {
  1179.             if (sscanf(bufPtr, "%d %d", &tmpVolId, &tmpTBufId) != 2) {
  1180.                 break;
  1181.             }
  1182.             if (tmpVolId == volId) {
  1183.                 volOwner.owner = Str_Dup(entryPtr->d_name);
  1184.             volOwner.minTBuf = tmpTBufId;
  1185.             volOwner.maxTBuf = INT_MAX;
  1186.             if (((bufPtr=Utils_ReadLine(fileStream, 1)) != NULL) &&
  1187.                 (sscanf(bufPtr, "%d %d",
  1188.                     &tmpVolId, &tmpTBufId)) == 2) {
  1189.                 volOwner.maxTBuf = tmpTBufId-1;
  1190.             }
  1191.             break;
  1192.             }
  1193.             }
  1194.             fclose(fileStream);
  1195.         }
  1196.     }
  1197.     }
  1198.  
  1199.     closedir(rootDirPtr);
  1200.  
  1201.     return &volOwner;
  1202. }
  1203.  
  1204.  
  1205. /*
  1206.  *----------------------------------------------------------------------
  1207.  *
  1208.  * Admin_ReadDevConfig --
  1209.  *
  1210.  *    Read the device configuration file
  1211.  *
  1212.  * Results:
  1213.  *    ptr to dynamic array.
  1214.  *
  1215.  * Side effects:
  1216.  *    None.
  1217.  *
  1218.  *----------------------------------------------------------------------
  1219.  */
  1220.  
  1221. int
  1222. Admin_ReadDevConfig(devFile, devList, cntPtr)
  1223.     char *devFile;            /* config file name */
  1224.     DevConfig *devList;       /* array space */
  1225.     int *cntPtr;              /* # slots (on input); # items (on output)*/
  1226. {
  1227.     int retCode = T_SUCCESS;
  1228.     FILE *configFile;
  1229.     char *bufPtr;
  1230.     char *locPtr;
  1231.     DevConfig *itemPtr = devList;
  1232.     int devCnt = 0;
  1233.  
  1234.     if ((configFile=fopen(devFile, "r")) == NULL) {
  1235.     syserr = errno;
  1236.     return T_FAILURE;
  1237.     }
  1238.     
  1239.     while ((bufPtr=Utils_ReadLine(configFile, 0)) != NULL) {
  1240.     devCnt++;
  1241.     }
  1242.  
  1243.     if (devCnt > *cntPtr) {
  1244.     syserr = ENOSPC;
  1245.     *cntPtr = devCnt;
  1246.     fclose(configFile);
  1247.     return T_FAILURE;
  1248.     }
  1249.  
  1250.     rewind(configFile);
  1251.  
  1252.     while ((bufPtr=Utils_ReadLine(configFile, 1)) != NULL) {
  1253.     locPtr = bufPtr;
  1254.     while ((*locPtr) && !isspace(*locPtr)) {
  1255.         locPtr++;
  1256.     }
  1257.     *locPtr++ = '\0';
  1258.     strcpy(itemPtr->name,bufPtr);
  1259.     if (Utils_CvtInteger(locPtr, 0, 5000, &itemPtr->location) != T_SUCCESS) {
  1260.         errno = 0;
  1261.         retCode = T_ADMFAILED;
  1262.         break;
  1263.     }
  1264.     itemPtr++;
  1265.     }
  1266.  
  1267.     fclose(configFile);
  1268.     return retCode;
  1269. }
  1270.  
  1271.  
  1272. /*
  1273.  *----------------------------------------------------------------------
  1274.  *
  1275.  * Admin_WriteDevConfig --
  1276.  *
  1277.  *    Write the device configuration file
  1278.  *
  1279.  * Results:
  1280.  *    return code.
  1281.  *
  1282.  * Side effects:
  1283.  *    None.
  1284.  *
  1285.  *----------------------------------------------------------------------
  1286.  */
  1287.  
  1288. int
  1289. Admin_WriteDevConfig(devFile, devList, cnt)
  1290.     char *devFile;            /* device file */
  1291.     DevConfig *devList;       /* array */
  1292.     int cnt;                  /* # slots */
  1293. {
  1294.     FILE *configFile;
  1295.     int retCode = T_SUCCESS;
  1296.     DevConfig *itemPtr = devList;
  1297.  
  1298.     if ((configFile=fopen(devFile, "w")) == NULL) {
  1299.     syserr = errno;
  1300.     return T_FAILURE;
  1301.     }
  1302.  
  1303.     while (cnt-- > 0) {
  1304.     fprintf(configFile, "%s %d", itemPtr->name, itemPtr->location);
  1305.     itemPtr++;
  1306.     }
  1307.  
  1308.     fclose(configFile);
  1309.     return retCode;
  1310.  
  1311. }
  1312.  
  1313. /*
  1314.  *----------------------------------------------------------------------
  1315.  *
  1316.  * Admin_ReadVolConfig --
  1317.  *
  1318.  *    Read the volume configuration file
  1319.  *
  1320.  * Results:
  1321.  *    return code.
  1322.  *
  1323.  * Side effects:
  1324.  *    None.
  1325.  *
  1326.  *----------------------------------------------------------------------
  1327.  */
  1328.  
  1329. int
  1330. Admin_ReadVolConfig(volFile, volList, cntPtr)
  1331.     char *volFile;            /* config file */
  1332.     VolConfig *volList;       /* array space */
  1333.     int *cntPtr;              /* # slots (on input); # items (on output)*/
  1334. {
  1335.     FILE *configFile;
  1336.     int volCnt = 0;
  1337.     char *bufPtr;
  1338.     int retCode = T_SUCCESS;
  1339.     VolConfig *itemPtr = volList;
  1340.  
  1341.     if ((configFile=fopen(volFile, "r")) == NULL) {
  1342.     syserr = errno;
  1343.     return T_FAILURE;
  1344.     }
  1345.     
  1346.     while ((bufPtr=Utils_ReadLine(configFile, 0)) != NULL) {
  1347.     volCnt++;
  1348.     }
  1349.  
  1350.     if (volCnt > *cntPtr) {
  1351.     syserr = ENOSPC;
  1352.     *cntPtr = volCnt;
  1353.     fclose(configFile);
  1354.     return T_FAILURE;
  1355.     }
  1356.  
  1357.     rewind(configFile);
  1358.  
  1359.     while ((bufPtr=Utils_ReadLine(configFile, 1)) != NULL) {
  1360.     if ((sscanf(bufPtr, "%s %d", 
  1361.             itemPtr->volLabel, &itemPtr->location) != 2) ||
  1362.         ((itemPtr->volId=Dev_CvtVolLabel(itemPtr->volLabel)) == -1)) {
  1363.         syserr = EINVAL;
  1364.         retCode = T_FAILURE;
  1365.         break;
  1366.     }
  1367.     itemPtr++;
  1368.     }
  1369.  
  1370.     fclose(configFile);
  1371.     return retCode;
  1372. }
  1373.  
  1374. /*
  1375.  *----------------------------------------------------------------------
  1376.  *
  1377.  * Admin_WriteVolConfig --
  1378.  *
  1379.  *    Write the volume configuration file
  1380.  *
  1381.  * Results:
  1382.  *    return code.
  1383.  *
  1384.  * Side effects:
  1385.  *    None.
  1386.  *
  1387.  *----------------------------------------------------------------------
  1388.  */
  1389.  
  1390. int
  1391. Admin_WriteVolConfig(volFile, volList, cnt)
  1392.     char *volFile;            /* config file */
  1393.     VolConfig *volList;       /* array */
  1394.     int cnt;                  /* # slots */
  1395. {
  1396.     FILE *configFile;
  1397.     int retCode = T_SUCCESS;
  1398.     VolConfig *itemPtr = volList;
  1399.  
  1400.     if ((configFile=fopen(volFile, "w")) == NULL) {
  1401.     syserr = errno;
  1402.     return T_FAILURE;
  1403.     }
  1404.  
  1405.     while (cnt-- > 0) {
  1406.     fprintf(configFile, "%s %d", itemPtr->volLabel, itemPtr->location);
  1407.     itemPtr++;
  1408.     }
  1409.  
  1410.     fclose(configFile);
  1411.     return retCode;
  1412.  
  1413. }
  1414.  
  1415.  
  1416.  
  1417. /*
  1418.  *----------------------------------------------------------------------
  1419.  *
  1420.  * Admin_GetFreeVol --
  1421.  *
  1422.  *    Get a new volume from the free pool.
  1423.  *
  1424.  * Results:
  1425.  *    Integer volume id and return code.
  1426.  *
  1427.  * Side effects:
  1428.  *    Updates the volume free pool file.
  1429.  *
  1430.  * Note:
  1431.  *      On entry, *volIdPtr is id of desired volume or -1 if any will do
  1432.  *
  1433.  * Quote:
  1434.  *      "I love deadlines. I like the whooshing sound 
  1435.  *      they make as they fly by."
  1436.  *      -- Douglas Adams
  1437.  *
  1438.  *----------------------------------------------------------------------
  1439.  */
  1440.  
  1441. int
  1442. Admin_GetFreeVol(root, volIdPtr)
  1443.     char *root;               /* root of Jaquith tree */
  1444.     int *volIdPtr;            /* receiving variable */
  1445. {
  1446.     FILE *volStream;
  1447.     FILE *newStream;
  1448.     char pathName[T_MAXPATHLEN];
  1449.     char newPathName[T_MAXPATHLEN];
  1450.     char *buf;
  1451.     int cnt = 0;
  1452.     int retCode = T_FAILURE;
  1453.     Lock_Handle lockHandle;
  1454.     int tmpVolId;
  1455.     int desiredVol = *volIdPtr;
  1456.  
  1457.     strcpy(pathName, root);
  1458.     strcat(pathName, FREESUFFIX);
  1459.     strcpy(newPathName, pathName);
  1460.     strcat(newPathName, FREENEWSUFFIX);
  1461.  
  1462.     if (Lock_Acquire(pathName, LOCK_BLOCK, &lockHandle) != T_SUCCESS) {
  1463.     return T_FAILURE;
  1464.     } else if ((volStream=fopen(pathName, "r")) == (FILE *)NULL) {
  1465.     Lock_Release(&lockHandle);
  1466.     return T_NOVOLUME;
  1467.     } else if ((newStream=fopen(newPathName, "w")) == (FILE *)NULL) {
  1468.     fclose(volStream);
  1469.     Lock_Release(&lockHandle);
  1470.     return T_NOVOLUME;
  1471.     } 
  1472.  
  1473.     while ((buf=Utils_ReadLine(volStream, 1)) != (char *)NULL) {
  1474.     if (Utils_CvtInteger(buf, 0, INT_MAX, &tmpVolId) != T_SUCCESS) {
  1475.         fclose(newStream);
  1476.         fclose(volStream);
  1477.         unlink(newPathName);
  1478.         Lock_Release(&lockHandle);
  1479.         return T_NOVOLUME;
  1480.     }
  1481.     if ((desiredVol == -1) || (desiredVol == tmpVolId)) {
  1482.         *volIdPtr = tmpVolId;
  1483.         retCode = T_SUCCESS;
  1484.         while ((buf=Utils_ReadLine(volStream, 0)) != (char *)NULL) {
  1485.         fputs(buf, newStream);
  1486.         cnt++;
  1487.         }
  1488.         break;
  1489.     } else {
  1490.         fputs(buf, newStream);
  1491.         fputc('\n', newStream);
  1492.         cnt++;
  1493.     }
  1494.     }
  1495.  
  1496.     /* Can't lose update or might assign the volume twice */
  1497.     fsync(fileno(newStream));
  1498.  
  1499.     fclose(newStream);
  1500.     fclose(volStream);
  1501.     unlink(pathName);
  1502.     rename(newPathName, pathName);
  1503.  
  1504.     Lock_Release(&lockHandle);
  1505.  
  1506.     if (cnt <= MINFREEVOLS) {
  1507.     sprintf(printBuf, "Warning: Only %d free volumes left in %s.\n",
  1508.         cnt, pathName);
  1509.     Utils_SendMail(ARCHMASTER, printBuf, "warning");
  1510.     }
  1511.  
  1512.     return retCode;
  1513. }
  1514.  
  1515.  
  1516. /*
  1517.  *----------------------------------------------------------------------
  1518.  *
  1519.  * Admin_PutFreeVol --
  1520.  *
  1521.  *    Add a new volume to the free pool.
  1522.  *
  1523.  * Results:
  1524.  *    Return code.  It's an error if volume already exists.
  1525.  *
  1526.  * Side effects:
  1527.  *    New volume will go at bottom of list.
  1528.  *
  1529.  *----------------------------------------------------------------------
  1530.  */
  1531.  
  1532. int
  1533. Admin_PutFreeVol(root, volId)
  1534.     char *root;               /* root of Jaquith tree */
  1535.     int volId;                /* receiving variable */
  1536. {
  1537.     FILE *volStream;
  1538.     FILE *newStream;
  1539.     char pathName[T_MAXPATHLEN];
  1540.     char newPathName[T_MAXPATHLEN];
  1541.     char *buf;
  1542.     int retCode = T_SUCCESS;
  1543.     Lock_Handle lockHandle;
  1544.     int tmpVolId;
  1545.  
  1546.     strcpy(pathName, root);
  1547.     strcat(pathName, FREESUFFIX);
  1548.     strcpy(newPathName, pathName);
  1549.     strcat(newPathName, FREENEWSUFFIX);
  1550.  
  1551.     if (Lock_Acquire(pathName, LOCK_BLOCK, &lockHandle) != T_SUCCESS) {
  1552.     return T_FAILURE;
  1553.     } else if ((volStream=fopen(pathName, "r")) == (FILE *)NULL) {
  1554.     Lock_Release(&lockHandle);
  1555.     return T_FAILURE;
  1556.     } else if ((newStream=fopen(newPathName, "w")) == (FILE *)NULL) {
  1557.     fclose(volStream);
  1558.     Lock_Release(&lockHandle);
  1559.     return T_FAILURE;
  1560.     } 
  1561.  
  1562.     while ((buf=Utils_ReadLine(volStream, 1)) != (char *)NULL) {
  1563.     if (Utils_CvtInteger(buf, 0, INT_MAX, &tmpVolId) != T_SUCCESS) {
  1564.         fclose(newStream);
  1565.         fclose(volStream);
  1566.         unlink(newPathName);
  1567.         Lock_Release(&lockHandle);
  1568.         syserr = EINVAL;
  1569.         return T_FAILURE;
  1570.     }
  1571.     if (volId == tmpVolId) {
  1572.         fclose(newStream);
  1573.         fclose(volStream);
  1574.         unlink(newPathName);
  1575.         Lock_Release(&lockHandle);
  1576.         syserr = EEXIST;
  1577.         return T_FAILURE;
  1578.     }
  1579.     fputs(buf, newStream);
  1580.     fputc('\n', newStream);
  1581.     }
  1582.  
  1583.     /* Ok, not found. Add it to list */
  1584.     fprintf(newStream, "%d\n", volId);
  1585.  
  1586.     fclose(newStream);
  1587.     fclose(volStream);
  1588.     unlink(pathName);
  1589.     rename(newPathName, pathName);
  1590.  
  1591.     Lock_Release(&lockHandle);
  1592.  
  1593.     return retCode;
  1594. }
  1595.